package io.gitee.xjt2016.modules.common;

import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import io.gitee.xjt2016.modules.common.config.JqGridTablePage;
import io.gitee.xjt2016.modules.service.sys.UserService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

@Log4j2
public class BaseController {

    protected <T> IPage<T> initMyBatisPage(BootStrapTablePage page) {
        return new Page<>(page.getPageNo(), page.getPageSize());
    }

    protected <T> IPage<T> initJqGridPage(JqGridTablePage page) {
        return new Page<>(page.getPage(), page.getRows());
    }

    protected <T> LambdaQueryWrapper<T> initQuery(JqGridTablePage page) {
        QueryWrapper<T> queryWrapper = new QueryWrapper<>();
        String orders = StringUtils.trim(page.getSidx()) + " " + StringUtils.trim(page.getSord());
        for (String sortSlot : StringUtils.split(orders, ",")) {
            String[] array = sortSlot.split(" ");
            if (array.length <= 1) {
                continue;
            }
            String column = array[0];
            String sort = array[1];
            if (StringUtils.isBlank(column) || StringUtils.isBlank(sort)) {
                continue;
            }
            if (StringUtils.equalsIgnoreCase("asc", sort)) {
                queryWrapper.orderByAsc(column);
            } else {
                queryWrapper.orderByDesc(column);
            }
        }
        return queryWrapper.lambda();
    }

    protected Map<Object, Object> pageResponse(IPage<?> page) {
        return MapUtil.builder()
                .put("rows", page.getRecords())
                .put("total", page.getTotal())
                .build();
    }

    protected Map<Object, Object> jqGridPageResponse(IPage<?> page) {
        return MapUtil.builder()
                .put("records", page.getTotal())//总数
                .put("total", page.getPages())//总页数
                .put("page", page.getCurrent())//当前页
                .put("rows", page.getRecords())//当前记录数
                .build();
    }

    protected Map<Object, Object> pageResponse(Collection<Object> list, Number total) {
        return MapUtil.builder()
                .put("rows", list)
                .put("total", total)
                .build();
    }

    protected List<String> split2List(String str) {
        if (str == null) {
            str = "";
        }
        return Arrays.stream(str.split("[,，]"))
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.toList());
    }

    protected List<Long> split2LongList(String str) {
        if (str == null) {
            str = "";
        }
        return Arrays.stream(str.split("[,，]"))
                .filter(StringUtils::isNotBlank)
                .map((Function<String, Long>) Long::valueOf)
                .collect(Collectors.toList());
    }

    protected String[] split2Array(String str) {
        if (str == null) {
            str = "";
        }
        return Arrays.stream(str.split("[,，]"))
                .filter(StringUtils::isNotBlank)
                .collect(Collectors.toList())
                .toArray(new String[]{});
    }

    protected boolean isConSpeCharacters(String string) {
        //如果不包含特殊字符
        return string.replaceAll("[\u4e00-\u9fa5]*[a-z]*[A-Z]*\\d*-*_*\\s*", "").length() == 0;
    }

    public HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

    /**
     * 从request中获得参数Map，并返回可读的Map
     *
     * @param request
     * @return
     */
    @SuppressWarnings({"unchecked", "rawtypes"})
    public static Map getParameterMap(HttpServletRequest request) {
        // 参数Map
        Map properties = request.getParameterMap();
        // 返回值Map
        Map returnMap = new HashMap();
        Iterator entries = properties.entrySet().iterator();
        Map.Entry entry;
        String name = "";
        String value = "";
        while (entries.hasNext()) {
            entry = (Map.Entry) entries.next();
            name = (String) entry.getKey();
            Object valueObj = entry.getValue();
            if (null == valueObj) {
                value = "";
            } else if (valueObj instanceof String[]) {
                String[] values = (String[]) valueObj;
                for (String value1 : values) {
                    value = value1 + ",";
                }
                value = value.substring(0, value.length() - 1);
            } else {
                value = valueObj.toString();
            }
            returnMap.put(name, value);
        }
        return returnMap;
    }

    protected String inputStream2String(InputStream in) throws IOException {
        InputStreamReader reader;

        reader = new InputStreamReader(in, StandardCharsets.UTF_8);

        BufferedReader br = new BufferedReader(reader);
        StringBuilder sb = new StringBuilder();
        String line;

        while ((line = br.readLine()) != null) {
            sb.append(line);
        }

        return sb.toString();
    }

    private static final Pattern pt = Pattern.compile("^[0-9a-zA-Z_]+$");

    public void checkUsername(String username) {
        Preconditions.checkArgument(StringUtils.isNotBlank(username), "用户名不能为空");
        //用户名密码校验
        boolean matched = false;
        //首先,使用Pattern解释要使用的正则表达式，其中^表是字符串的开始，$表示字符串的结尾。

        //然后使用Matcher来对比目标字符串与上面解释得结果
        Matcher mt = pt.matcher(username);
        //如果能够匹配则返回true。实际上还有一种方法mt.find()，某些时候，可能不是比对单一的一个字符串，
        //可能是一组，那如果只要求其中一个字符串符合要求就可以用find方法了.
        if (mt.matches()) {
            matched = true;
        }
        Preconditions.checkArgument(matched, "用户名不符合规范，请输入1-16位的由字母、数字、下划线组成的字符串");
    }


    public WebResponse buildResponse(Object data, Integer result) {
        WebResponse webResponse = new WebResponse();
        webResponse.setData(data);
        webResponse.setResult(result);
        return webResponse;
    }

    public WebResponse buildResponse(boolean result) {
        return buildResponse(result, result ? 100 : 300);
    }

    public WebResponse buildSuccessResponse(Object data) {
        WebResponse webResponse = new WebResponse();
        webResponse.setData(data);
        webResponse.setResult(100);
        return webResponse;
    }

    public WebResponse buildSuccessResponse() {
        WebResponse webResponse = new WebResponse();
        webResponse.setData("success");
        webResponse.setResult(100);
        return webResponse;
    }

    public WebResponse buildFailedResponse(String message) {
        WebResponse webResponse = new WebResponse();
        webResponse.setData(message);
        webResponse.setResult(300);
        return webResponse;
    }

    public WebResponse buildFailedResponse(String message, Integer result) {
        WebResponse webResponse = new WebResponse();
        webResponse.setMessage(message);
        webResponse.setResult(result);
        return webResponse;
    }

    protected ModelAndView buildRedirectModelAndView(String url) {
        return new ModelAndView("redirect:" + url);
    }

    @Autowired
    UserService userService;
}
